# @Time : 2020/7/17 15:11
# @Author : Fioman 
# @Phone : 13149920693

"""
灰度图像是 0~255之间的一个数字.其实是一个8位的数.这个数可以变相表示为
a7*2^7 + a6*2^6 + a5*2^5 + a4*2^4 + a3*2^3 + a2*2^2 + a1*2^1 + a0*2^0
其中ai的值可以是0或者1, 我们可以将对应bit位上的值组成一个新的图像,也就是8副图像.
图像中全部像素值在ai所构成的位平面,称为第i个位平面.(第i层.)
位平面分解之后的值都是0和1,权重是2^i次方.

构造提取位平面的矩阵.
使用按位与操作能够很方便的将一个数值指定位上的数字提取出来.
例如:建立一个值均为2^n的Mat作为提取矩阵,用来与原始图像进行按位与运算.就可以提取第n个位平面.

阈值处理:
通过计算得到的位平面是一个二值图像,如果直接将上述得到的位平面显示出来,就会得到一张近似黑色的图像.
这是因为默认当前显示的图像是8位灰度图,而当其中的像素值较小时,显示的图像就会是近似黑色的.
例如, 在图像RD中,最大的像素值是8,因此几乎纯黑色.要想让8显示为白色,必须将8处理为255

也就是说,每次提取位平面以后,要想让二值位平面能够以黑白颜色显示出来,就要将得到的二值位平面进行阈值处理,将其中大于零的值处理为255.
mask = RD[:,:,i] > 0
将RD中大于0的值处理为逻辑值真(True)
将RD中小于等于0的值处理为逻辑值假(False)
RD[mask] = 255
将RD中对应的mask中逻辑值为真的位置的值替换为255.
"""

import cv2 as cv
import numpy as np

lena = cv.imread("lena.bmp", cv.IMREAD_GRAYSCALE)
cv.imshow("lena", lena)
r, c = lena.shape

# 创建分解位图的Mat矩阵
mat = np.zeros((r, c, 8), dtype=np.uint8)
for i in range(8):
    mat[:, :, i] = 2 ** i

r = np.zeros((r,c,8),dtype=np.uint8)

# 将位平面分解,根据上面的分解矩阵
for i in range(8):
    r[:,:,i] = cv.bitwise_and(lena,mat[:,:,i])
    mask = r[:,:,i] > 0
    r[mask] = 255
    cv.imshow(str(i),r[:,:,i])

cv.waitKey(0)
cv.destroyAllWindows()

























